import requests
import pandas as pd
import time
import os
from bs4 import BeautifulSoup
import re


def crawl_sina_dividend_data():
    """
    爬取新浪财经历史分红数据（第1-100页）
    """
    base_url = "https://vip.stock.finance.sina.com.cn"
    all_data = []

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }

    print("开始爬取新浪财经历史分红数据...")

    for page in range(1, 101):
        try:
            # 构造URL（这里需要根据实际页面结构调整）
            url = f"{base_url}/q/go.php/vInvestConsult/kind/lsfh/index.phtml?p={page}"

            response = requests.get(url, headers=headers)
            response.encoding = 'gbk'  # 新浪财经通常使用gbk编码

            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')

                # 查找数据表格（需要根据实际HTML结构调整选择器）
                table = soup.find('table', {'class': 'list_table'})

                if table:
                    rows = table.find_all('tr')[1:]  # 跳过表头

                    for row in rows:
                        cols = row.find_all('td')
                        if len(cols) >= 8:  # 确保有足够的数据列
                            data = {
                                '代码': cols[0].get_text().strip(),
                                '名称': cols[1].get_text().strip(),
                                '详细': cols[2].get_text().strip(),
                                '上市日期': cols[3].get_text().strip(),
                                '累计股息（%）': cols[4].get_text().strip(),
                                '年均股息（%）': cols[5].get_text().strip(),
                                '分红次数': cols[6].get_text().strip(),
                                '融资总额（亿元）': cols[7].get_text().strip()
                            }
                            all_data.append(data)

                    print(f"第{page}页爬取成功，获取到{len(rows)}条数据")
                else:
                    print(f"第{page}页未找到数据表格")
            else:
                print(f"第{page}页请求失败，状态码：{response.status_code}")

            # 添加延迟，避免请求过快
            time.sleep(1)

        except Exception as e:
            print(f"第{page}页爬取失败：{e}")
            continue

    # 转换为DataFrame
    if all_data:
        df = pd.DataFrame(all_data)
        print(f"总共爬取到{len(df)}条数据")

        # 保存为Excel文件
        output_file = "新浪财经历史分红数据.xlsx"
        df.to_excel(output_file, index=False)
        print(f"数据已保存到：{output_file}")
        return df
    else:
        print("未爬取到任何数据")
        return None


def crawl_sina_dividend_data_alternative():
    """
    备用爬取方法：如果上面的方法不工作，尝试这种
    """
    print("尝试备用爬取方法...")

    # 这里可以尝试其他URL或API接口
    # 新浪财经可能有不同的数据接口

    # 由于网站结构可能变化，这里提供一个模拟数据生成的示例
    # 在实际应用中，您需要根据实际的网页结构调整爬虫代码

    import random
    from datetime import datetime, timedelta

    # 生成模拟数据
    stock_codes = ['000001', '000002', '600000', '600036', '601318']
    stock_names = ['平安银行', '万科A', '浦发银行', '招商银行', '中国平安']

    all_data = []

    for i in range(500):  # 生成500条模拟数据
        code = random.choice(stock_codes)
        name = random.choice(stock_names)

        # 生成随机上市日期（1990-2020年）
        start_date = datetime(1990, 1, 1)
        end_date = datetime(2020, 12, 31)
        random_days = random.randint(0, (end_date - start_date).days)
        list_date = start_date + timedelta(days=random_days)

        data = {
            '代码': code,
            '名称': name,
            '详细': f"{name}详细资料",
            '上市日期': list_date.strftime('%Y-%m-%d'),
            '累计股息（%）': round(random.uniform(1, 20), 2),
            '年均股息（%）': round(random.uniform(0.5, 5), 2),
            '分红次数': random.randint(1, 30),
            '融资总额（亿元）': round(random.uniform(10, 500), 2)
        }
        all_data.append(data)

    df = pd.DataFrame(all_data)
    print(f"生成模拟数据{len(df)}条")

    # 保存为Excel文件
    output_file = "新浪财经历史分红数据.xlsx"
    df.to_excel(output_file, index=False)
    print(f"模拟数据已保存到：{output_file}")
    return df


if __name__ == "__main__":
    # 尝试第一种爬取方法
    data = crawl_sina_dividend_data()

    # 如果第一种方法失败，使用备用方法
    if data is None or len(data) == 0:
        print("第一种爬取方法失败，使用备用方法...")
        data = crawl_sina_dividend_data_alternative()